package cn.biplam.front.template.control;

import java.util.ArrayList;

import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;
import cn.biplam.common.wrapper.Result;
import cn.biplam.common.wrapper.UserInfo;
import cn.biplam.front.callback.CallBack;
import cn.biplam.front.html.HtmlDiv;
import cn.biplam.front.html.base.HtmlWindow;
import cn.biplam.front.html.base.Const.Length_Unit;
import cn.biplam.front.html.base.Const.Position_Mode;
import cn.biplam.front.template.control.rfFlowTable.callback.content.BaseContentCallback;
import cn.biplam.front.template.control.rfFlowTable.callback.content.IndexColCallback;
import cn.biplam.front.template.control.table.DimTable;
import cn.biplam.front.template.control.table.Table;
import cn.biplam.front.template.control.table.cell.ThCell;

/**
 * 数据查看表格,表格用于只需要查看数据集数据无需操作的情况
 * <ul>用法：
 * <li> DataViewTable table = new DataViewTable('应用系统路径','用户信息','表格页面ID','表格需要绑定的数据集');   创建表格
 * <li> table.putCol('列名','列标题','列宽度','列内容绑定器(可选)');                                           设置表格列
 * <li>  设置分页信息（可选）<BR>
 * 		table.setPageProperty('分页跳转动作ID','分页记录ID','分页跳转目标ID'); <BR>
 *      putPageAddParam(参数名,参数值)方法 设置放入分页所需附加参数<BR>
 * <li> table.setRemoveRepeatCol(列名称列表)                                                               设置剔除重复数据列
 * <li> table.get();																					  获取表格
 * </ul>
 * @author XiaoRuxing Sep 1, 20094:55:58 PM
 * @version 1.0
 */
public class DataViewTable extends DimTable{

	/** 内容 */
	private Table table;
	
	/** 每列宽度 */
	private KvMap<String, Integer> colWidth;
	/** 每列对应标题 */
	private KvMap<String, String> colTitle;
	/** 列对应的回调器 */
	private KvMap<String, CallBack> colCallback;
	
	/** 宽度 */
	private int tableWidth;
	/** 高度 */
	private int iOutHeight=-1;
	/** 表格绑定数据集为空时的提示信息 */
	private String emptyInfo = "&nbsp;";
	
	/** 表格行索引列列名 */
	public final String INDEX_COL_NAME = ".dtViewIndexName";
	
	/**
	 * 创建数据查看表
	 * @param sHomeUrl 应用系统路径
	 * @param mUser    用户信息
	 * @param pageID   表格页面ID
	 * @param rs       需要绑定的数据集
	 * @throws ErrorMessage 
	 */
	public DataViewTable(String sHomeUrl,UserInfo mUser,String pageID,OperatorResult rs) throws ErrorMessage{
		super(sHomeUrl, mUser, pageID,rs);
		_init();
	}
	
	/**
	 * 设置每列信息
	 * @param sColFieldName 列对应数据集字段名
	 * @param iColSize     列宽度(列字符个数)
	 * @throws ErrorMessage 
	 */
	public void putCol(String sColFieldName,String sColTitle,int iColSize) throws ErrorMessage{
		this.putCol(sColFieldName, sColTitle, iColSize,new BaseContentCallback(sColFieldName));
	}
	
	/**
	 * 设置每列信息
	 * @param sColFieldName 列对应数据集字段名
	 * @param iColWidth     列宽度
	 * @throws ErrorMessage 
	 */
	public void putCol(String sColFieldName, String sColTitle ,String sColWidth) throws ErrorMessage{
		this.putCol(sColFieldName,sColTitle, sColWidth, new BaseContentCallback(sColFieldName));
	}
	
	/**
	 * 设置每列信息
	 * @param sColFieldName 列对应数据集字段名
	 * @param iColSize     列宽度(列字符个数)
	 * @param colCallback   列内容回调器
	 * @throws ErrorMessage 
	 */
	public void putCol(String sColFieldName,String sColTitle,int iColSize,CallBack colCallback) throws ErrorMessage{
		int width = TOOLS.getPxLength(iColSize);
		this.putCol(sColFieldName, sColTitle, TOOLS.intToString(width), colCallback);
	}
	
	/**
	 * 设置每列信息
	 * @param sColFieldName 列对应数据集字段名
	 * @param iColWidth     列宽度
	 * @param colCallback   列内容回调器
	 * @throws ErrorMessage 
	 */
	public void putCol(String sColFieldName,String sColTitle,String sColWidth,CallBack colCallback) throws ErrorMessage{
		this._setColFieldName(sColFieldName);
		this._setColSize(sColFieldName, TOOLS.stringToInt(sColWidth));
		this.colTitle.put(sColFieldName,sColTitle);
		if(colCallback!=null){
			this._setColCallback(sColFieldName, colCallback);
		}
	}
	
	/**
	 *  设置是否显示行索引
	 * @param isShowRowIndex 是否显示行索引
	 * @throws ErrorMessage 
	 */
	public void setShowRowIndex(boolean isShowRowIndex) throws ErrorMessage{
		this.colFieldName.add(0,INDEX_COL_NAME);
		this.colWidth.put(INDEX_COL_NAME, TOOLS.getPxLength(3));
		this.colTitle.put(INDEX_COL_NAME, "  ");
		this._setColCallback(INDEX_COL_NAME, new IndexColCallback());
	}
	
	/**
	 * @return  表格宽度
	 */
	public int getWidth(){
		return this.tableWidth;
	}
	
	/**
	 *  设置高度
	 * @param height 高度值
	 */
	public void setHeight(int height) throws ErrorMessage{
		this.iOutHeight = height;
	}
	
	/**
	 * 获取表格
	 * @return 表格页面对象
	 */
	public HtmlWindow get() throws ErrorMessage{
		this.table=new Table(pageID);
		_setTableTitle();
		_setContent();
		HtmlWindow page = getPageProperty();
		this.table.setStyle("border-top", "0");
		
		HtmlWindow tb = this.table.get();
		//设置表格大小
		tb.setStyle("overflow-y", "auto");
		tb.setStyleWidth(this.tableWidth);
		if(this.iOutHeight>0){
			tb.bind("dataViewTableResize('"+tb.getID()+"',"+this.iOutHeight+");");
		}
		//设置标题行不滚动
		HtmlWindow title = table.getRow(0);
		title.setPositionMode(Position_Mode.Relative);
		title.setTop("expression(this.offsetParent.scrollTop)",Length_Unit.empty);
		//放入分页对象
		HtmlWindow outTable = new HtmlDiv(this.outerContainerId);
		outTable.put(tb);
		if(page!=null){
			outTable.put(page);
		}
		return outTable;
	}
	
	private void _init() throws ErrorMessage{
		this.colCallback = new KvMap<String, CallBack>();
		this.colFieldName = new ArrayList<String>();
		this.colTitle = new KvMap<String, String>();
		this.colWidth = new KvMap<String, Integer>();
		this.tableWidth = 0;
	}
	
	/**
	 * 设置表格标题行
	 * @throws ErrorMessage
	 */
	private void _setTableTitle() throws ErrorMessage{
		int i=0;
		String colTitle = null;
		int colWidth;
		for(String col:this.colFieldName){
			colTitle = this.colTitle.getByKey(col);
			colWidth = this.colWidth.getByKey(col);
			table.put(new ThCell(colTitle).get(), 0, i,Table.Table_Cell_Type.TH);
			table.setColWidth(String.valueOf(colWidth), 0, i);
			this.tableWidth+=colWidth;
			i++;
		}
	}
	
	/**
	 * 设置表格内容
	 * @throws ErrorMessage
	 */
	private void _setContent() throws ErrorMessage{
		//剔重列
		if(TOOLS.exist(this.rs)){
			Result result = rs.getResult();
			while(result.next()){
				for(String col:this.colFieldName){
					_putCol(result.getCurrentRow()+1, col, this.colFieldName.indexOf(col), result);
				}
			}
		}else{//不存在数据创建空行
			_createNullCol();
		}
	}
	
	/**
	 * 设置分页属性
	 * @throws ErrorMessage 
	 */
	private HtmlWindow getPageProperty() throws ErrorMessage{
		HtmlWindow page = this.getPageProperty(rs, outerContainerId, pageID, tableWidth,this.table);
		if(page!=null){
			//设置表格占位高度为外面传入高度减去分页行高度
			if(this.iOutHeight>pageComp.getHeight()){
				this.iOutHeight = iOutHeight-pageComp.getHeight();
			}
		}
		return page;
	}
	
	/**
	 *  创建空行
	 * @throws ErrorMessage 
	 */
	private void _createNullCol() throws ErrorMessage{
		this.table.put(
				new HtmlDiv(null,null,this.emptyInfo),
				1,
				TOOLS.intToString(this.colFieldName.size()));
	}
	
	/**
	 * 设置单元格内容
	 * @throws ErrorMessage
	 */
	private void _putCol(int row,String colName,int colIndex,Result result) throws ErrorMessage{
		CallBack callback = this.colCallback.getByKey(colName);
		if(callback!=null){
			table.put(createCol(sHomeUrl, mUser, callback, null, null, recordId, result, colIndex, colName),
					row,
					colIndex);
		}else{
			throw new ErrorMessage("DataView col "+colName+" content is null!");
		}
		table.setColWidth(String.valueOf(this.colWidth.getByKey(colName)), row, colIndex);
	}
	
	/**
	 * 设置行宽度
	 * @throws ErrorMessage 
	 */
	private void _setColSize(String colName, int size) throws ErrorMessage{
		if(size<0){
			throw new ErrorMessage(" The size of "+colName+" is invalid!");
		}
		this.colWidth.put(colName, size);
	}
	
	/**
	 * 设置行对应字段名（不允许重复）
	 * @param colName 字段名
	 * @throws ErrorMessage
	 */
	private void _setColFieldName(String colName) throws ErrorMessage{
		if(this.colFieldName.indexOf(colName)>=0){
			throw new ErrorMessage(colName+" is duplicate define!");
		}
		this.colFieldName.add(colName);
	}
	
	/**
	 * 设置列回调器
	 */
	private void _setColCallback(String colName,CallBack callback) throws ErrorMessage{
		this.colCallback.put(colName, callback);
	}
}
